//============================================================================
// Name        : MUL8_Onboard_Android_COMM.cpp
// Author      : Darryl Ramgoolam, Jerrell Jones, Adam Stroud
// Version     :
// Copyright   : 
// Description : This is the server in MUL8's android to linux communication protocol.
/**
 * This server will be connected to by the android phone, which does most of the specifying of IP and Ports.
 * The only communication realted value that needs to be set in this server is MY_PORT.
 * MY_PORT must match "rosPort", which is found in line 87 of the android (client) part of the code.
 * The IP address of this PC must be known and set in the client as well.
 */
//============================================================================




#include <stdio.h>
#include <string>
#include <time.h>
#include <string.h>
#include <cstdlib>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "Android_Control.h"

std::string standStr= "stand";
std::string walkStr= "walk";
std::string kickStr= "kick";
std::string relaxStr= "relax";
std::string engageStr= "engage";
std::string trackStr= "track";
std::string emptyStr= "empty";


int sockfd;
struct sockaddr_in self;
char buffer[MAXBUF];
int ret = 0;
int clientfd;
struct sockaddr_in client_addr;
socklen_t addrlen=sizeof(client_addr);

Android_Control::Android_Control()
{
	openConnection();
}

Android_Control::~Android_Control(){
}

void Android_Control::openConnection(){

#ifdef UDP
   	/*---Create datagram socket---*/
   	if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
   	    {
   		printf("i am a datagram, unreliable socket");
   		perror("Socket");
   		exit(errno);
   	}
#else
    /*---Create streaming socket---*/
   	else if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    {
    	printf("i am a streaming, reliable socket");
    	perror("Socket");
    	exit(errno);
    }
#endif



    /*---Initialize address/port structure---*/
    memset(&self,0,sizeof(self));
    self.sin_family = AF_INET;
    self.sin_port = htons(MY_PORT);
    self.sin_addr.s_addr = htonl(INADDR_ANY);

    /*---Assign a port number to the socket---*/
    if ( bind(sockfd, (struct sockaddr*)&self, sizeof(self)) != 0 )
    {
    	perror("socket--bind");
    	exit(errno);
    }

//#ifndef UDP
    //*---Make it a nonblocking socket---*/

 //   if(fcntl(sockfd, F_SEFTL, flags | O_NONBLOCK)!=0){
  //  	printf("could not make non blocking\n");
   // 	exit(errno);
 //   }
//#endif

#ifndef UDP
    /*---Make it a "listening socket"---*/

    if ( listen(sockfd, 20) != 0 )
    {
    	perror("socket--listen");
    	exit(errno);
    }
#endif

  // TODO experimental in the step functino. was in openconnection()
#ifndef UDP
        /*---accept a connection (creating a data pipe)---*/
        clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &addrlen);
        printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
#endif

}

/* called from MUL8.cpp to check if a button is pressed*/
int Android_Control::step(bool isListening){


	if(isListening){


/* TODO make these non-blocking commands. if they were not, the CPU would sit here until it got something in the socket*/
#ifndef UDP
		ret = recv(clientfd, buffer, MAXBUF, 0);
		printf(buffer+ "\n");
		//printf("recv %d\n", recv(clientfd, buffer, MAXBUF, 0));
#else

		ret = recvfrom(sockfd,buffer,MAXBUF,0,(struct sockaddr *)&client_addr,&addrlen);
		printf("got buffer");
#endif

		/*Check which button was pressed on the phone. each returns a code to MUL8.cpp*/
		if(buffer==standStr){
			return 1;
		}
		else if(buffer==walkStr){
			return 2;
		}
		else if(buffer==kickStr){
			return 3;
		}
		else if(buffer==relaxStr){
			return 4;
		}
		else if(buffer==engageStr){
			return 5;
		}
		else if(buffer==trackStr){
			return 6;
		}
		else if(buffer==emptyStr){
			return 7;
		}
		memset(buffer, 0, MAXBUF);




	}


#ifndef UDP
	close(clientfd);
	printf("closed clientfd\n");
#endif
//	printf("closed clientfd\n");

	/*---Clean up (should never get here!)---*/
//	close(sockfd);
 //}

	return 0;
}

// TODO delete this probably
void Android_Control::closeConnection(){
	close(clientfd);
	close(sockfd);
}
